Tensorflow lite在Android端部署 |
您所在的位置:网站首页 › patotso lite安卓 › Tensorflow lite在Android端部署 |
最近一个项目需要使用Tensorflow lite, 官网上的解释又特别简单,主要给了一个例子,但是这个例子和官网的解释又不一样。。。。这里简单记录下操作方法。 添加依赖某些加载的方法,依赖并不支持。 在自己的build.grandle的依赖中添加: implementation 'org.tensorflow:tensorflow-lite:1.15.0' implementation 'org.tensorflow:proto:1.15.0' 模型转化对于keras或者用model建立的模型,有直接的转化函数,对于sess建立的模型(计算图),有很多方法不再适用。我尝试了一种是可以使用的: 先转化为saved model通过saved model 转化为tflite file转化为saved model: tf.saved_model.simple_save( sess, "%s/trained model/flows" % (savedir), inputs={"input": input}, outputs={"flows": flows} )注意:其中的inputs和outputs必须是张量,否则会提醒你array没有name属性。 inputs就是feed_dict中那些place holder,outputs可以填输出的张量,也可以直接填操作本身。 转为tflite file: import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(path) tflite_model = converter.convert() open(path+"/converted_model.tflite", "wb").write(tflite_model)至此得到了tflite文件 模型加载注意点: 1: 读取文件时需要申请权限 2: 对于Interpreter的构造函数,只有MappedByteBuffer那个可以使用,用File的那个会报错。 直接把生成的文件放在“我的手机”中,如果是虚拟机,则是storage/emulated/0文件夹下,然后使用 Environment.getExternalStorageDirectory().getPath();后面加上文件名称,可以得到该文件的路径。 文件加载函数: public MappedByteBuffer getFile(String fileName) throws IOException { File f = new File(fileName); FileInputStream in = new FileInputStream(f); FileChannel channel = in.getChannel(); return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); }把该函数返回的作为Interpreter的输入,可以生成一个解释器。 权限申请: 在manifest中增加: 对于Android11以下的版本,需要额外增加: android:requestLegacyExternalStorage="true"申请权限: // Storage Permissions private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; public static void verifyStoragePermissions(Activity activity) { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user ActivityCompat.requestPermissions( activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } } 推理有两个函数可以使用: 单输入输出 interpreter.run(inputs, outputs);inputs和ouputs都是高维数组,比如正常的都是: float[][][][] inputs = new float[1][h][w][3];注意不管是输入还是输出,数组申请空间时候必须把每一个维度都确定,否则可能导致拷贝出错或者维度出错。 比如: Caused by: java.lang.IllegalStateException: Internal error: Unexpected failure when preparing tensor allocations: tensorflow/lite/kernels/concatenation.cc:74 t->dims->data[d] != t0->dims->data[d] (1 != 2) Node number 9 (CONCATENATION) failed to prepare. 输入维度错误,或者没有给定输入的维度 ouputs也是多维数组,和inputs相同。 多输入 interpreter.runForMultipleInputsOutputs([Objects], outputs)第一个参数是一个数组,里面是输入的张量。我猜测顺序和convert函数中命名的字典序有关。如果不放心的话,可以使用: Tensor a = interpreter.getInputTensor(0);然后看一下copyShape是否符合。 因此,如果张量是4维的,那么第一个参数是一个5维的数组。 outputs是一个Map,可以声明如下: Map outputs = HashMap(); outputs.put(0,Objects); 其他将Bitmap转为float数组: public Bitmap toBitmap(float[][][] a){ int[] colors = new int[h_res*w_res]; for(int i = 0; i int r = (int)(a[j][i][0]*255) & 0xff; int g = (int)(a[j][i][1]*255) & 0xff; int b = (int)(a[j][i][2]*255) & 0xff; colors[i*h_res+j] = 0xff000000 | (r for (int j = 0; j |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |